import { NextFunction, Request, Response } from 'express'
import Joi from 'joi'
import { AppError } from './errorHandler'

export const validate = (schema: Joi.ObjectSchema) => {
  return (req: Request, res: Response, next: NextFunction) => {
    const { error } = schema.validate(req.body)
    if (error) {
      throw new AppError(error.details[0].message, 400)
    }
    next()
  }
}

export const schemas = {
  auth: {
    register: Joi.object({
      username: Joi.string().min(3).max(30).required(),
      password: Joi.string().min(6).required(),
      nickname: Joi.string().min(2).max(30).required(),
    }),
    login: Joi.object({
      username: Joi.string().required(),
      password: Joi.string().required(),
    }),
  },
  room: {
    create: Joi.object({
      name: Joi.string().min(3).max(50).required(),
      recordingEnabled: Joi.boolean().default(true),
    }),
  },
  payment: {
    create: Joi.object({
      amount: Joi.number().positive().required(),
      currency: Joi.string().length(3).default('cny'),
    }),
  },
  game: {
    create: Joi.object({
      roomId: Joi.string().required(),
    }),
  },
  gift: {
    send: Joi.object({
      roomId: Joi.string().required(),
      giftId: Joi.string().required(),
      amount: Joi.number().integer().min(1).max(99).default(1),
    }),
  },
  admin: {
    gift: Joi.object({
      action: Joi.string().valid('enable', 'disable', 'update').required(),
      name: Joi.string().min(2).max(50).when('action', {
        is: 'update',
        then: Joi.required(),
      }),
      price: Joi.number().positive().when('action', {
        is: 'update',
        then: Joi.required(),
      }),
      description: Joi.string().max(200).when('action', {
        is: 'update',
        then: Joi.required(),
      }),
      animation: Joi.object({
        type: Joi.string().valid('simple', 'advanced', 'special'),
        url: Joi.string().uri(),
        duration: Joi.number().positive(),
        scale: Joi.number().positive(),
        sound: Joi.string(),
      }).when('action', {
        is: 'update',
        then: Joi.required(),
      }),
    }),
    room: Joi.object({
      action: Joi.string().valid('close', 'ban').required(),
      reason: Joi.string().max(200).when('action', {
        is: 'ban',
        then: Joi.required(),
      }),
      duration: Joi.number().positive().when('action', {
        is: 'ban',
        then: Joi.required(),
      }),
    }),
  },
  notification: {
    markAsRead: Joi.object({
      notificationIds: Joi.array().items(Joi.string()).min(1).required(),
    }),
    delete: Joi.object({
      notificationIds: Joi.array().items(Joi.string()).min(1).required(),
    }),
  },
}
